home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / sviluppo / svilupp2 / amphn192.lha / src / browse.c < prev    next >
C/C++ Source or Header  |  1996-11-16  |  19KB  |  730 lines

  1. /* Module for the voice mail browser window */
  2.  
  3. #ifndef BROWSE_C
  4. #define BROWSE_C
  5.  
  6. #include <stdio.h>
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h> 
  10. #include <string.h>
  11. #include <time.h>
  12.  
  13. #include <dos/dos.h>
  14. #include <dos/dostags.h>
  15. #include <dos/dosextens.h>
  16. #include <dos/var.h>
  17. #include <dos/exall.h>
  18.  
  19. #include <intuition/intuition.h>
  20. #include <intuition/intuitionbase.h>
  21. #include <intuition/gadgetclass.h>
  22. #include <intuition/screens.h>
  23. #include <libraries/gadtools.h>
  24. #include <exec/ports.h>
  25. #include <exec/memory.h>
  26. #include <exec/types.h>
  27. #include <exec/tasks.h>
  28. #include <exec/io.h>
  29. #include <exec/libraries.h>
  30. #include <libraries/dos.h>            /* contains RETURN_OK, RETURN_WARN #def's */
  31. #include <libraries/gadtools.h>
  32.  
  33. #include <clib/alib_protos.h>
  34. #include <clib/dos_protos.h>
  35. #include <clib/exec_protos.h>
  36. #include <clib/intuition_protos.h>
  37. #include <clib/graphics_protos.h>
  38. #include <clib/gadtools_protos.h>
  39. #include <clib/diskfont_protos.h>
  40.  
  41. #include "amiphone.h"
  42. #include "codec.h"
  43. #include "messages.h"
  44. #include "browse.h"
  45.  
  46. #define UNLESS(x) if(!(x))
  47. #define HSPACE 10
  48. #define VSPACE 6
  49. #define BUTTONHEIGHT 16
  50. #define BUTTONWIDTH(x) (10*strlen(x))
  51. #define NUMBUTTONS 5
  52.  
  53. #define GAD_LISTVIEW    0
  54. #define GAD_PLAY    1
  55. #define GAD_STOP    2
  56. #define GAD_KILL    3
  57. #define GAD_SCAN    4
  58. #define GAD_EXIT    5
  59.  
  60. #define LAST_ENABLED    2
  61.  
  62. /* private data */
  63. static struct GfxBase * GfxBase       = NULL;
  64. static struct Library * IntuitionBase = NULL;
  65. static struct Library * GadToolsBase  = NULL;
  66. static struct List    * FileList      = NULL;
  67. static struct Window  * BrowseWindow  = NULL;
  68. static struct Gadget  * glist         = NULL,
  69.               * listviewgad   = NULL,
  70.               * playbutton    = NULL,
  71.               * killbutton    = NULL,
  72.                       * gad           = NULL;
  73. static struct NewGadget ng;
  74. static void           * vi            = NULL;
  75. static int              windowleft    = -1,
  76.                         windowtop     = -1,
  77.                         windowheight  = 140,
  78.                         windowwidth   = 555;
  79. static ULONG            ulLastIndexClicked;
  80. static char * szMessageDir;
  81. static BOOL Not[2] = {TRUE,FALSE};
  82.  
  83. static struct TextAttr Topaz80 = { "topaz.font", 8, 0, 0, };
  84. static struct Process * BrowserProcess = NULL; 
  85. extern struct Screen * Scr;
  86.  
  87. /* private functions */
  88. struct List * ReadFileList      (char * szDirectory);
  89. struct Node * MakeNode          (char * szNewName, char * szNewComment);
  90. void          FreeDoubleString  (char * DoubleString);
  91. void          PrintDoubleString (char * DoubleString);
  92. void          ClearFileList     (struct List * thislist);
  93. void          PrintFileList     (struct List * list);
  94. void           ListClicked       (int nIndex, struct MsgPort * ReplyPort);
  95. void          PlayCurrentFile   (struct MsgPort * ReplyPort);
  96. void          KillFile          (struct MsgPort * ReplyPort);     
  97. void          AttachList        (BOOL BAttach);
  98. void           EnableFileOps     (BOOL BEnable);
  99. BOOL           DoIDCMP            (struct IntuiMessage * defaultMessage, struct MsgPort * ReplyPort);
  100. BOOL          AllocGadgets      (BOOL BAlloc, struct List * NameList);
  101. BOOL          RemoveCurrentFile (void);
  102. char *        GetCurrentFile    (char ** szOptSetCommentString);
  103.  
  104.  
  105.  
  106.  
  107.  
  108. BOOL AllocGadgets(BOOL BAlloc, struct List * NameList)
  109. {
  110.     int nStep;
  111.     
  112.     /* Make everything NULL, etc. */
  113.     memset(&ng, '\0', sizeof(ng));
  114.     
  115.     if (BAlloc == TRUE)
  116.     {
  117.         UNLESS(vi = GetVisualInfo(Scr,TAG_END)) return(FALSE);
  118.         gad = CreateContext(&glist);
  119.  
  120.         /* Allocate ListView */        
  121.         ng.ng_TextAttr   = &Topaz80;
  122.         ng.ng_VisualInfo = vi;
  123.         ng.ng_LeftEdge   = HSPACE;
  124.         ng.ng_TopEdge    = VSPACE + Scr->WBorTop+Scr->Font->ta_YSize;
  125.         ng.ng_Width      = windowwidth-(HSPACE<<1);
  126.         ng.ng_Height     = windowheight-ng.ng_TopEdge-(VSPACE*3)-BUTTONHEIGHT;
  127.         ng.ng_GadgetID   = GAD_LISTVIEW;
  128.         listviewgad = gad = CreateGadget(LISTVIEW_KIND, gad, &ng,
  129.             GTLV_Labels,    NameList,  TAG_END);
  130.  
  131.         /* get spacing step for the buttons! */
  132.         nStep = ng.ng_Width / NUMBUTTONS;
  133.         
  134.         /* Allocate Play button */
  135.         ng.ng_TopEdge    += ng.ng_Height + (VSPACE/2);
  136.         ng.ng_LeftEdge   += (nStep-BUTTONWIDTH("XXXX"))/2;    /* center! */
  137.         ng.ng_Width      = BUTTONWIDTH("Play");
  138.         ng.ng_Height     = BUTTONHEIGHT;
  139.         ng.ng_GadgetText = "Play";
  140.         ng.ng_GadgetID   = GAD_PLAY;
  141.         playbutton = gad = CreateGadget(BUTTON_KIND, gad, &ng, GA_Disabled, TRUE, TAG_END);
  142.  
  143.         /* Allocate Stop button */
  144.         ng.ng_LeftEdge  += nStep;
  145.         ng.ng_Width      = BUTTONWIDTH("Stop");
  146.         ng.ng_Height     = BUTTONHEIGHT;
  147.         ng.ng_GadgetText = "Stop";
  148.         ng.ng_GadgetID   = GAD_STOP;
  149.         gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  150.  
  151.         /* Allocate Delete button */
  152.         ng.ng_LeftEdge  += nStep;
  153.         ng.ng_Width      = BUTTONWIDTH("Kill");
  154.         ng.ng_Height     = BUTTONHEIGHT;
  155.         ng.ng_GadgetText = "Kill";
  156.         ng.ng_GadgetID   = GAD_KILL;
  157.         killbutton = gad = CreateGadget(BUTTON_KIND, gad, &ng, GA_Disabled, TRUE, TAG_END);
  158.  
  159.         /* Allocate Scan button */
  160.         ng.ng_LeftEdge  += nStep;
  161.         ng.ng_Width      = BUTTONWIDTH("Scan");
  162.         ng.ng_Height     = BUTTONHEIGHT;
  163.         ng.ng_GadgetText = "Scan";
  164.         ng.ng_GadgetID   = GAD_SCAN;
  165.         gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  166.  
  167.         /* Allocate Exit button */
  168.         ng.ng_LeftEdge  += nStep;
  169.         ng.ng_Width      = BUTTONWIDTH("Exit");
  170.         ng.ng_Height     = BUTTONHEIGHT;
  171.         ng.ng_GadgetText = "Exit";
  172.         ng.ng_GadgetID   = GAD_EXIT;
  173.         gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  174.     }
  175.     else
  176.     {
  177.         if ((BrowseWindow)&&(glist)) RemoveGList(BrowseWindow, glist, -1);
  178.         if (glist) {FreeGadgets(glist); glist = NULL;}
  179.  
  180.         /* Mark gadgets as free */
  181.         playbutton = NULL;
  182.         killbutton = NULL;
  183.         gad = NULL;
  184.         listviewgad = NULL;
  185.         
  186.         if (vi)    {FreeVisualInfo(vi); vi = NULL;}
  187.     }    
  188.     return(TRUE);
  189. }
  190.  
  191.  
  192. /* Read all the filenames in the directory into our list */
  193. struct List * ReadFileList(char * szDirectory)
  194. {
  195.     BPTR MyLock = Lock(szDirectory, ACCESS_READ);
  196.     BOOL BMore;
  197.     struct ExAllControl * eac;
  198.     struct ExAllData * ead;
  199.     __aligned UBYTE EAData[sizeof(struct ExAllData)*30];
  200.     struct List * FileList = NULL;
  201.     struct Node * newnode;
  202.     
  203.     if (MyLock == 0) 
  204.     {
  205.         printf("ReadFileList: Lock of [%s] failed.\n",szDirectory); 
  206.         return(NULL);
  207.     }
  208.     
  209.     eac = AllocDosObject(DOS_EXALLCONTROL,NULL);
  210.     if (eac == NULL)
  211.     {
  212.         printf("ReadFileList: AllocDosObject failed.\n");
  213.         UnLock(MyLock);
  214.         return(NULL);    
  215.     }
  216.     
  217.     UNLESS(FileList = AllocMem(sizeof(struct List), MEMF_CLEAR))
  218.     {
  219.         printf("ReadFileList: Couldn't allocate FileList\n");
  220.         FreeDosObject(DOS_EXALLCONTROL, eac);    
  221.         UnLock(MyLock);
  222.         return(NULL);
  223.     }
  224.     NewList(FileList);
  225.  
  226.     eac->eac_Entries = 30;
  227.     eac->eac_MatchString = NULL;
  228.     eac->eac_MatchFunc = NULL;    
  229.     eac->eac_LastKey = 0;    /* very important! */
  230.  
  231.     do 
  232.     {
  233.         BMore = ExAll(MyLock, (struct ExAllData *) EAData, sizeof(EAData), ED_COMMENT, eac);
  234.         if ((!BMore)&&(IoErr() != ERROR_NO_MORE_ENTRIES)) 
  235.         {
  236.             printf("ReadFileList: ExAll terminated abnormally.\n"); 
  237.             break;
  238.         }
  239.         if (eac->eac_Entries == 0)
  240.         {
  241.             /* ExAll has no more entries? */
  242.             continue;    /* more is *usually* zero */
  243.         }
  244.         
  245.         ead = (struct ExAllData *) EAData;
  246.         do {
  247.             if (newnode = MakeNode(ead->ed_Name, ead->ed_Comment)) AddTail(FileList,newnode);
  248.             ead = ead->ed_Next;
  249.         } while (ead);
  250.     } while (BMore);
  251.  
  252.     FreeDosObject(DOS_EXALLCONTROL, eac);    
  253.     UnLock(MyLock);
  254.     return(FileList);
  255. }
  256.  
  257.  
  258. /* Node will have a text entry that is two strings--first the displayable
  259.    string, and then the filename "hidden" behind it. */
  260. struct Node * MakeNode(char * szNewName, char * szNewNote)
  261. {
  262.     struct Node *newnode;
  263.     char * szNodeName, * pcTemp = NULL;
  264.     int nNameLength, nCommentLength;
  265.     char szFileName[400];
  266.     
  267.     if (szNewName == NULL) return(NULL);
  268.  
  269.     nNameLength = strlen(szNewName);
  270.  
  271.     /* In case there is no file comment, just give the file name */
  272.     if (szNewNote == NULL)
  273.     {
  274.         strcpy(szFileName,"  (");
  275.         strncat(szFileName,szNewName,sizeof(szFileName)-3);
  276.         strcat(szFileName,")");
  277.         szNewNote = szFileName;
  278.     }
  279.     else
  280.     {
  281.         /* Hack to avoid this silly '?' at the beginning of comments! */
  282.         if ((*szNewNote != 'N')&&(*szNewNote != ' ')) szNewNote++;
  283.     }
  284.     
  285.     nCommentLength = strlen(szNewNote);
  286.         
  287.     /* And ANOTHER hack to avoid unterminated strings!  Aack! */
  288.     if (nCommentLength > 63) nCommentLength = 63;
  289.         
  290.     /* Allocate fields for new node */
  291.      if ((newnode    = AllocMem(sizeof(struct Node), MEMF_CLEAR)) &&
  292.         (szNodeName = AllocMem(nNameLength+nCommentLength+2, MEMF_CLEAR)))
  293.     {
  294.         /* copy in the strings */
  295.         Strncpy(szNodeName, szNewNote, nCommentLength+1);
  296.         Strncpy(szNodeName+nCommentLength+1, szNewName, nNameLength+1);
  297.                 
  298.         /* Fill out Node with a pointer to the string */
  299.         newnode->ln_Name = szNodeName;
  300.         
  301.         /* return our new baby */
  302.         return(newnode);
  303.     }
  304.     else
  305.     {
  306.         /* Free up any data we allocated */
  307.         if (szNodeName) FreeMem(szNodeName, nNameLength+nCommentLength+2);
  308.         if (newnode) FreeMem(newnode, sizeof(struct Node));
  309.                 
  310.         /* fail */
  311.         return(NULL);
  312.     }
  313. }
  314.  
  315.  
  316.  
  317. /* Frees the space of the two strings */
  318. void FreeDoubleString(char * szDoubleString)
  319. {
  320.     int nLen;
  321.     
  322.     if (szDoubleString == NULL) return;
  323.     
  324.     nLen =  strlen(szDoubleString) + 1;
  325.     nLen += strlen(szDoubleString + nLen + 1) + 1;
  326.     FreeMem(szDoubleString, nLen);
  327. }
  328.  
  329.  
  330.  
  331. void PrintDoubleString(char * szDoubleString)
  332. {
  333.     printf("file:    [%s]\n",szDoubleString+strlen(szDoubleString)+1);
  334.     printf("comment: [%s]\n",szDoubleString);
  335. }
  336.  
  337.  
  338.  
  339. void ClearFileList(struct List * thislist)
  340. {
  341.     struct Node *current;
  342.             
  343.     while (current = RemHead(thislist))
  344.     {
  345.         if (current->ln_Name != NULL) 
  346.             FreeDoubleString(current->ln_Name);
  347.         FreeMem(current,sizeof(struct Node));   
  348.     }
  349.     return;
  350. }
  351.  
  352.  
  353.  
  354. void PrintFileList(struct List * list)
  355. {
  356.     struct Node * current = list->lh_Head;
  357.     
  358.     while (current->ln_Succ)
  359.     {
  360.         PrintDoubleString(current->ln_Name);
  361.         current = current->ln_Succ;
  362.     }
  363. }
  364.  
  365. /* If non-NULL, szOptCommentString will return a pointer to the comment. */
  366. /* The function returns a pointer to the filename */
  367. char * GetCurrentFile(char ** szOptCommentString)
  368. {
  369.     struct Node * current = FileList->lh_Head;
  370.     int i = ulLastIndexClicked;
  371.     
  372.     if (i >= 0)
  373.     {
  374.         while (current->ln_Succ)
  375.         {
  376.             if (szOptCommentString != NULL) *szOptCommentString = current->ln_Name;
  377.             if (i == 0) return(current->ln_Name + strlen(current->ln_Name) + 1);
  378.             current = current->ln_Succ;
  379.             i--;
  380.         }
  381.     }
  382.     return("[NULL]");
  383. }
  384.  
  385. /* Removes the current file from the list */
  386. BOOL RemoveCurrentFile(void)
  387. {
  388.     struct Node * current = FileList->lh_Head;
  389.     int i = ulLastIndexClicked;
  390.     
  391.     if (i < 0) return(FALSE);
  392.         
  393.     AttachList(FALSE);
  394.     
  395.     while (current->ln_Succ)
  396.     {
  397.         if (i == 0)     /* found the target */
  398.         {
  399.             Remove(current);    /* take from the list */
  400.             FreeDoubleString(current->ln_Name);    /* free mem */
  401.             FreeMem(current, sizeof(struct Node));
  402.             AttachList(TRUE);        /* update list */
  403.             ulLastIndexClicked = -1;    /* no more current file */
  404.             EnableFileOps(FALSE);
  405.             return(TRUE);
  406.         }
  407.         current = current->ln_Succ;
  408.         i--;
  409.     }
  410.     AttachList(TRUE);    
  411.     return(FALSE);
  412. }
  413.  
  414. void AttachList(BOOL BAttach)
  415. {
  416.     if ((listviewgad == NULL)||(BrowseWindow == NULL)) return;
  417.     
  418.     if (BAttach == TRUE)
  419.           GT_SetGadgetAttrs((struct Gadget *)listviewgad, BrowseWindow, NULL, GTLV_Labels, FileList, TAG_END);
  420.     else  GT_SetGadgetAttrs((struct Gadget *)listviewgad, BrowseWindow, NULL, GTLV_Labels, ~0, TAG_END);
  421. }
  422.  
  423.  
  424.  
  425. void PlayCurrentFile(struct MsgPort * ReplyPort)
  426. {
  427.     char * szCommentString, * szFileName;
  428.     static char szTemp[300];
  429.     
  430.     /* Don't ever launch two at once!  Stop the first one here and then try again */
  431.     StopPlayer(ReplyPort);
  432.     
  433.     /* Get file name and comment string of current file */
  434.     szFileName = GetCurrentFile(&szCommentString);
  435.  
  436.     Strncpy(szTemp,szMessageDir,sizeof(szTemp));
  437.     UNLESS(AddPart(szTemp,szFileName,sizeof(szTemp))) return;
  438.     
  439.     /* Remove any "new" tag from file */
  440.     if ((szCommentString != NULL)&&(*szCommentString == 'N'))
  441.     {
  442.         AttachList(FALSE);
  443.         *szCommentString = ' ';    /* Remove the N, it's no longer new */
  444.         SetComment(szTemp,szCommentString);
  445.         AttachList(TRUE);
  446.     }
  447.     
  448.     /* Put in a request to play the file */
  449.     SendPlayerMessage(MESSAGE_CONTROLMAIN_PLAYFILE, szTemp, 0L, ReplyPort);
  450.     
  451.     Delay(15);    /* okay, so I suck.  Sigh... */
  452. }
  453.  
  454.  
  455.  
  456. void StopPlayer(struct MsgPort * ReplyPort)
  457. {
  458.     SendPlayerMessage(MESSAGE_CONTROLMAIN_STOPPLAYING, NULL, 0L, ReplyPort);
  459. }
  460.  
  461.  
  462.  
  463. void KillFile(struct MsgPort * ReplyPort)
  464. {
  465.     char szTemp[300];
  466.  
  467.     StopPlayer(ReplyPort);
  468.  
  469.     Strncpy(szTemp,szMessageDir,sizeof(szTemp));
  470.     if (AddPart(szTemp,GetCurrentFile(NULL), sizeof(szTemp))) 
  471.     {
  472.         remove(szTemp);        /* from disk */
  473.         RemoveCurrentFile();    /* from our display */
  474.     }
  475.         
  476. }
  477.  
  478. /* Takes the appropriate action depending on what item was clicked. */
  479. void ListClicked(int nIndex, struct MsgPort * ReplyPort)
  480. {
  481.     static time_t tLastTimeClicked;
  482.     time_t tPreviousTimeClicked = tLastTimeClicked;
  483.     
  484.     tLastTimeClicked = time(NULL);
  485.     EnableFileOps(TRUE);
  486.         
  487.     if ((nIndex == ulLastIndexClicked)&&
  488.        ((tLastTimeClicked - tPreviousTimeClicked) < 2))
  489.         PlayCurrentFile(ReplyPort);
  490.         
  491.     ulLastIndexClicked = nIndex;
  492. }
  493.  
  494.  
  495. /* Enables/disables the "Play" and "Kill" buttons. */
  496. void EnableFileOps(BOOL BEnable)
  497. {
  498.     static BOOL BLast = FALSE;
  499.     
  500.     if (BEnable == LAST_ENABLED) BEnable = BLast;
  501.     
  502.     GT_SetGadgetAttrs(playbutton, BrowseWindow, NULL, GA_Disabled, Not[BEnable]);
  503.     GT_SetGadgetAttrs(killbutton, BrowseWindow, NULL, GA_Disabled, Not[BEnable]);
  504.  
  505.     BLast = BEnable;
  506. }
  507.  
  508.  
  509. /* Scans and/or rescans the file lists, and updates them. */
  510. void ScanFiles(void)
  511. {
  512.     AttachList(FALSE);
  513.     
  514.     /* Get rid of the old list */
  515.     if (FileList != NULL) 
  516.     {
  517.         ClearFileList(FileList);
  518.         FreeMem(FileList, sizeof(struct List));
  519.     }    
  520.     
  521.     /* And read in the new one */
  522.     FileList = ReadFileList(szMessageDir);
  523.     
  524.     AttachList(TRUE);
  525. }
  526.  
  527. /* Returns TRUE if program should exit */
  528. BOOL DoIDCMP(struct IntuiMessage * defaultMessage, struct MsgPort * ReplyPort)
  529. {
  530.     struct IntuiMessage *message = NULL;
  531.     ULONG class, code, qual; /* , ulItemCode; */
  532.     /* struct MenuItem *mItem; */
  533.     static LONG lCode;
  534.     BOOL BProgramDone = FALSE;
  535.     struct Gadget * gad;
  536.     
  537.     /* Get the first message from the queue, or use the one we already have */
  538.     if (defaultMessage == NULL) message = (struct IntuiMessage *) GT_GetIMsg(BrowseWindow->UserPort);
  539.                    else message = defaultMessage;
  540.  
  541.     /* Examine pending messages */    
  542.     while (message != NULL)
  543.     {
  544.         class = message->Class;        /* extract needed info from message */
  545.         code  = message->Code;
  546.         qual  = message->Qualifier;
  547.         gad   = (struct Gadget *) message->IAddress;
  548.  
  549.         /* tell Intuition we got the message */
  550.         GT_ReplyIMsg(message);
  551.  
  552.         /* see what events occured, take correct action */
  553.         switch(class)
  554.         {    
  555.             case IDCMP_GADGETUP:
  556.                 switch(gad->GadgetID)
  557.                 {
  558.                     case GAD_LISTVIEW: ListClicked(code,ReplyPort);   break;
  559.                     case GAD_PLAY:     PlayCurrentFile(ReplyPort);   break;
  560.                     case GAD_STOP:     StopPlayer(ReplyPort);        break;
  561.                     case GAD_KILL:     KillFile(ReplyPort); break;
  562.                     case GAD_SCAN:     ScanFiles();       break;
  563.                     case GAD_EXIT:       BProgramDone = TRUE; break;
  564.                 }
  565.                 break;
  566.  
  567.             case IDCMP_NEWSIZE:
  568.                 AllocGadgets(FALSE,NULL);
  569.                 EraseRect(BrowseWindow->RPort,BrowseWindow->BorderLeft, BrowseWindow->BorderTop,
  570.                       BrowseWindow->Width - BrowseWindow->BorderRight - 1,
  571.                       BrowseWindow->Height - BrowseWindow->BorderBottom - 1);
  572.                 RefreshWindowFrame(BrowseWindow);
  573.                 windowwidth  = BrowseWindow->Width;
  574.                 windowheight = BrowseWindow->Height;
  575.                 if (AllocGadgets(TRUE,FileList))
  576.                 {
  577.                     AddGList(BrowseWindow, glist, -1, -1, NULL);
  578.                     RefreshGList(glist, BrowseWindow, NULL, -1);
  579.                     GT_RefreshWindow(BrowseWindow, NULL);
  580.                 }
  581.                 EnableFileOps(LAST_ENABLED);
  582.                 break;
  583.                 
  584.             case IDCMP_REFRESHWINDOW:
  585.                 GT_BeginRefresh(BrowseWindow);
  586.                 GT_EndRefresh(BrowseWindow, TRUE);
  587.                 break;
  588.                     
  589.             case IDCMP_CLOSEWINDOW: 
  590.                 BProgramDone = TRUE;  
  591.                 break;
  592.                 
  593.             case IDCMP_VANILLAKEY:
  594.                 break;
  595.                 
  596.             default:        break;
  597.         }
  598.     
  599.         /* Only do the one message if it's a custom message */
  600.         if (defaultMessage != NULL) return(BProgramDone);
  601.  
  602.         /* Get next message from the queue */
  603.         message = (struct IntuiMessage *)GT_GetIMsg(BrowseWindow->UserPort);
  604.     }
  605.     return(BProgramDone);
  606. }
  607.  
  608.  
  609. void StopBrowser(void)
  610. {
  611.     Signal((struct Task *)BrowserProcess,SIGBREAKF_CTRL_C);
  612. }
  613.  
  614. void StartBrowser(char * szMessageDirArg)
  615. {
  616.     szMessageDir = szMessageDirArg;
  617.     
  618.     UNLESS(BrowserProcess = CreateNewProcTags(
  619.         NP_Entry,     BrowserMain, 
  620.         NP_Name,      "AmiPhone Message Browser",
  621.         NP_Priority,    0, 
  622.         NP_Output,    stdout,
  623.         NP_CloseOutput, FALSE,
  624.         NP_Cli,        TRUE,
  625.         TAG_END))
  626.         printf("Couldn't create browser task\n");
  627. }
  628.  
  629.  
  630. __geta4 void BrowserMain(void)
  631. {    
  632.     ULONG ulBrowseMask = SIGBREAKF_CTRL_C, ulSignals;
  633.     struct MsgPort *BrowserReplyPort = CreatePort(0,0);
  634.     
  635.     ulLastIndexClicked = -1;
  636.     
  637.     UNLESS(BrowserReplyPort) goto Cleanup;    
  638.  
  639.     /* Tell main we're on */    
  640.     SendPlayerMessage(MESSAGE_CONTROLMAIN_BROWSEROPEN, NULL, 0L, BrowserReplyPort);
  641.  
  642.     /* Open required libraries */
  643.     UNLESS((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37))
  644.          &&(IntuitionBase = OpenLibrary("intuition.library",37))
  645.          &&(GadToolsBase = OpenLibrary("gadtools.library",37))) goto Cleanup;
  646.  
  647.     /* Populate the list */
  648.     ScanFiles();
  649.     UNLESS(FileList)
  650.     {
  651.         printf("Couldn't read list of files/notes\n");
  652.         goto Cleanup;
  653.     }
  654.  
  655.     UNLESS(AllocGadgets(TRUE,FileList))
  656.     {
  657.         printf("Couldn't allocate gadgets.\n");
  658.         goto Cleanup;
  659.     }
  660.  
  661.     
  662.     /* center if necessary */
  663.     if (windowleft < 0) windowleft = (Scr->Width-windowwidth)/2;
  664.     if (windowtop  < 0) windowtop  = (Scr->Height-windowheight)/2; 
  665.     
  666.     /* Open up our window */
  667.     UNLESS(BrowseWindow = OpenWindowTags( NULL,
  668.         WA_Left,        windowleft,
  669.             WA_Top,         windowtop,
  670.                    WA_Width,       windowwidth,
  671.             WA_Height,      windowheight,
  672.             WA_MinWidth,    260,
  673.             WA_MinHeight,    60+Scr->WBorTop+Scr->RastPort.TxHeight+1,
  674.             WA_MaxWidth,    -1,
  675.             WA_MaxHeight,    -1,
  676.             WA_PubScreen,   Scr,
  677.             WA_PubScreenFallBack, TRUE,
  678.             WA_IDCMP,       IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|SLIDERIDCMP|IDCMP_NEWSIZE,
  679.             WA_Flags,       WFLG_SIZEBBOTTOM|WFLG_SMART_REFRESH|WFLG_ACTIVATE|
  680.                     /*WFLG_NEWLOOKMENUS|*/WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  681.                     WFLG_DEPTHGADGET,
  682.             WA_Gadgets,    glist,
  683.         WA_Title,       "AmiPhone Message Browser",
  684.                WA_DepthGadget, TRUE,
  685.                WA_CloseGadget, TRUE,
  686.                WA_SizeGadget,  TRUE,
  687.                WA_DragBar,    TRUE,
  688.                WA_AutoAdjust,  TRUE,
  689.                WA_Activate,    TRUE,
  690.         TAG_DONE ))
  691.     {
  692.         printf("Couldn't open Browser window!\n");
  693.         goto Cleanup;
  694.     }
  695.     GT_RefreshWindow(BrowseWindow, NULL);
  696.     
  697.     /* Wait on signal for the window */
  698.     ulBrowseMask |= (1<<BrowseWindow->UserPort->mp_SigBit);
  699.     
  700.     /* The event loop */
  701.     while(1)
  702.     {
  703.         ulSignals = Wait(ulBrowseMask);
  704.         if (ulSignals & SIGBREAKF_CTRL_C) break;
  705.         if ((ulSignals & (1<<BrowseWindow->UserPort->mp_SigBit))&&(DoIDCMP(NULL,BrowserReplyPort))) break;
  706.     }        
  707.     
  708. Cleanup:
  709.     if (BrowseWindow  != NULL) {CloseWindow(BrowseWindow); BrowseWindow = NULL;}
  710.     AllocGadgets(FALSE,NULL);
  711.     if (FileList != NULL) 
  712.     {
  713.         ClearFileList(FileList);
  714.         FreeMem(FileList, sizeof(struct List));
  715.         FileList = NULL;    /* Unset it for the next task? */
  716.     }
  717.     
  718.     if (GadToolsBase  != NULL) {CloseLibrary(GadToolsBase); GadToolsBase = NULL;}
  719.     if (IntuitionBase != NULL) {CloseLibrary(IntuitionBase); IntuitionBase = NULL;}
  720.     if (GfxBase       != NULL) {CloseLibrary(GfxBase); GfxBase = NULL;}
  721.  
  722.     /* Tell main we're gone */    
  723.     SendPlayerMessage(MESSAGE_CONTROLMAIN_BROWSERCLOSED, NULL, 0L, BrowserReplyPort);
  724.     
  725.     /* Cleanup any remaining messages and close the port */
  726.     if (BrowserReplyPort) {RemovePortSafely(BrowserReplyPort); BrowserReplyPort = NULL;}
  727. }
  728.  
  729. #endif
  730.